home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / dfue / term 4.6(?) / extras / source / term-source.lha / StatusDisplay.c < prev    next >
C/C++ Source or Header  |  1996-03-18  |  29KB  |  1,363 lines

  1. /*
  2. **    StatusDisplay.c
  3. **
  4. **    Status information display routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* The information to be displayed. */
  17.  
  18. enum    {
  19.             INFO_STATUS,INFO_BUFFER,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
  20.             INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST,
  21.             INFO_UNITTIME
  22.         };
  23.  
  24.     /* The current status line display mode. */
  25.  
  26. enum    {
  27.             MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,
  28.             MODE_WB_NORMAL,MODE_WB_COMPRESSED
  29.         };
  30.  
  31.     /* Enumerated text boxes. */
  32.  
  33. enum    {
  34.             STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
  35.             STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE
  36.         };
  37.  
  38.     // What to show in the online time box.
  39.  
  40. enum    {
  41.             SHOW_Cost,SHOW_OnlineTime,SHOW_UnitTime
  42.         };
  43.  
  44.     /* The status server passes this structure to the
  45.      * rendering routine if the status information
  46.      * is to be updated.
  47.      */
  48.  
  49. struct ObjectCarrier
  50. {
  51.     struct RastPort     *RPort;
  52.     LONG              FirstColumn,
  53.                       FullWidth;
  54.     struct TextBox    **BoxArray,
  55.                      *BoxList;
  56. };
  57.  
  58.     /* A custom message type for the display update server. */
  59.  
  60. struct UpdateMessage
  61. {
  62.     struct Message    VanillaMessage;
  63.  
  64.     APTR            Object;
  65.     UBYTE            Mode,
  66.                     Type;
  67. };
  68.  
  69.     /* The following static strings are displayed in the status
  70.      * window.
  71.      */
  72.  
  73. STATIC STRPTR             ConfigBufferState[3],
  74.                          ConfigEmulation[6],
  75.                          ConfigParity[6],
  76.                          ConfigStatus[8];
  77.  
  78.     /* Width of the status line text, required in case the user interface
  79.      * font happens to be proportional-spaced.
  80.      */
  81.  
  82. STATIC LONG                 StatusLineWidth;
  83.  
  84.     /* The status display update task. */
  85.  
  86. STATIC struct Task        *StatusDisplayTask;
  87. STATIC struct MsgPort    *StatusDisplayPort;
  88.  
  89.     /* Display update data */
  90.  
  91. STATIC WORD                 UpdateSig;
  92. STATIC ULONG             UpdateMask;
  93. STATIC BOOLEAN             NeedFullRefresh;
  94.  
  95. STATIC VOID
  96. DrawSeparator(struct RastPort *RPort)
  97. {
  98.     LONG    Left    = StatusDisplayLeft,
  99.             Width    = StatusDisplayWidth;
  100.  
  101.     SetAPen(RPort,Pens[SHADOWPEN]);
  102.     Move(RPort,Left,StatusDisplayTop);
  103.     Draw(RPort,Left + Width - 1,StatusDisplayTop);
  104.  
  105.     SetAPen(RPort,Pens[SHINEPEN]);
  106.     Move(RPort,Left,StatusDisplayTop + 1);
  107.     Draw(RPort,Left + Width - 1,StatusDisplayTop + 1);
  108. }
  109.  
  110.     /* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  111.      *
  112.      *    Display information in the status line area.
  113.      */
  114.  
  115. STATIC VOID
  116. DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  117. {
  118.         /* What mode of operation is the status area in? */
  119.  
  120.     switch(Mode)
  121.     {
  122.             /* Compressed mode. */
  123.  
  124.         case MODE_SCREEN_COMPRESSED:
  125.         {
  126.             struct RastPort *RPort = Object;
  127.  
  128.             STATIC BYTE Offsets[8] =
  129.             {
  130.                  0,
  131.                 -1,    /* Not supported */
  132.                 26,
  133.                 11,
  134.                 40,
  135.                 53,
  136.                 61,
  137.                 72
  138.             };
  139.  
  140.             STATIC UBYTE Strings[8][20];
  141.             UBYTE LineBuffer[90];
  142.             LONG i,j,k,Width;
  143.  
  144.             strcpy(Strings[Type],String);
  145.  
  146.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  147.  
  148.             for(i = 0 ; i < 8 ; i++)
  149.             {
  150.                 if(Offsets[i] >= 0)
  151.                 {
  152.                     j = strlen(Strings[i]);
  153.  
  154.                     for(k = 0 ; k < j ; k++)
  155.                         LineBuffer[Offsets[i] + k] = Strings[i][k];
  156.                 }
  157.             }
  158.  
  159.             Width = TextLength(RPort,LineBuffer,80);
  160.  
  161.             if(RPort->Layer)
  162.             {
  163.                 if(AttemptLockLayerRom(RPort->Layer))
  164.                 {
  165.                     if((StatusLineWidth && StatusLineWidth != Width) || NeedFullRefresh)
  166.                     {
  167.                         LONG OldPen = ReadAPen(RPort);
  168.  
  169.                         SetAPen(RPort,Pens[TEXTPEN]);
  170.                         FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  171.                         SetAPen(RPort,OldPen);
  172.  
  173.                         StatusLineWidth = Width;
  174.                         NeedFullRefresh = FALSE;
  175.                     }
  176.  
  177.                     PlaceText(RPort,StatusDisplayLeft + (StatusDisplayWidth - Width) / 2,StatusDisplayTop,LineBuffer,80);
  178.  
  179.                     UnlockLayerRom(RPort->Layer);
  180.                 }
  181.             }
  182.         }
  183.  
  184.         break;
  185.  
  186.             /* Normal mode. */
  187.  
  188.         case MODE_SCREEN_NORMAL:
  189.         {
  190.             STATIC UBYTE Codes[8][2] =
  191.             {
  192.                 STATUSBOX_STATUS_FONT,            0,
  193.                 STATUSBOX_STATUS_FONT,            1,
  194.  
  195.                 STATUSBOX_PROTOCOL_TERMINAL,    0,
  196.                 STATUSBOX_PROTOCOL_TERMINAL,    1,
  197.  
  198.                 STATUSBOX_RATE_PARAMETERS,        0,
  199.                 STATUSBOX_RATE_PARAMETERS,        1,
  200.  
  201.                 STATUSBOX_TIME_ONLINE,            0,
  202.                 STATUSBOX_TIME_ONLINE,            1
  203.             };
  204.  
  205.             struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
  206.  
  207.             if(Carrier->RPort && Carrier->RPort->Layer)
  208.             {
  209.                 if(AttemptLockLayerRom(Carrier->RPort->Layer))
  210.                 {
  211.                     if(NeedFullRefresh && !Config->ScreenConfig->SplitStatus)
  212.                     {
  213.                         struct RastPort    *RPort = Carrier->RPort;
  214.                         LONG             Left;
  215.  
  216.                         if((Left = StatusDisplayLeft + (StatusDisplayWidth - Carrier->FullWidth) / 2) < 0)
  217.                             Left = 0;
  218.  
  219.                         Left += Carrier->FirstColumn - SZ_GetBoxInfo(Carrier->BoxList,BOX_LEFT);
  220.  
  221.                         SetAPen(RPort,Pens[BACKGROUNDPEN]);
  222.                         FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  223.  
  224.                         DrawSeparator(RPort);
  225.  
  226.                         SZ_SetBoxes(Carrier->BoxList,-1,StatusDisplayTop + 3);
  227.                         SZ_MoveBoxes(Carrier->BoxList,Left,0);
  228.  
  229.                         SZ_DrawBoxes(RPort,Carrier->BoxList);
  230.  
  231.                         NeedFullRefresh = FALSE;
  232.                     }
  233.  
  234.                     SZ_PrintLine(Carrier->RPort,Carrier->BoxArray[Codes[Type][0]],Codes[Type][1],String);
  235.  
  236.                     UnlockLayerRom(Carrier->RPort->Layer);
  237.                 }
  238.             }
  239.         }
  240.  
  241.         break;
  242.     }
  243. }
  244.  
  245.     /* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  246.      *
  247.      *    Post an update message to the status display server.
  248.      */
  249.  
  250. STATIC VOID
  251. DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  252. {
  253.     struct UpdateMessage    *Msg;
  254.     LONG                     Len = strlen(String) + 1;
  255.  
  256.         /* Allocate enough space to hold both the string
  257.          * and the message.
  258.          */
  259.  
  260.     if(Msg = (struct UpdateMessage *)AllocVecPooled(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  261.     {
  262.             /* Fill in the message head. */
  263.  
  264.         Msg->VanillaMessage.mn_Length = sizeof(struct UpdateMessage) + Len;
  265.  
  266.             /* Set up the name pointer. */
  267.  
  268.         Msg->VanillaMessage.mn_Node.ln_Name = (STRPTR)(Msg + 1);
  269.  
  270.             /* Copy the string. */
  271.  
  272.         strcpy(Msg->VanillaMessage.mn_Node.ln_Name,String);
  273.  
  274.             /* Fill in the remaining data. */
  275.  
  276.         Msg->Object    = Object;
  277.         Msg->Mode        = Mode;
  278.         Msg->Type        = Type;
  279.  
  280.             /* Post the message. */
  281.  
  282.         PutMsg(StatusDisplayPort,(struct Message *)Msg);
  283.     }
  284. }
  285.  
  286.     /* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
  287.      *
  288.      *    Update the information displayed in the status
  289.      *    area.
  290.      */
  291.  
  292. STATIC VOID __stdargs
  293. UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
  294. {
  295.     if(Object)
  296.     {
  297.         UBYTE     MiniBuffer[50];
  298.         STRPTR    *String;
  299.         LONG    *Numeral;
  300.         va_list     VarArgs;
  301.  
  302.         va_start(VarArgs,Type);
  303.  
  304.         String    = (STRPTR *)VarArgs;
  305.         Numeral    = (LONG *)VarArgs;
  306.  
  307.         switch(Type)
  308.         {
  309.             case INFO_STATUS:
  310.  
  311.                 memcpy(MiniBuffer,ConfigStatus[Numeral[0]],9);
  312.                 strcat(MiniBuffer,"         ");
  313.  
  314.                 MiniBuffer[9] = 0;
  315.  
  316.                 break;
  317.  
  318.             case INFO_BUFFER:
  319.  
  320.                 if(Mode == MODE_SCREEN_NORMAL)
  321.                     DoInfo(Object,Mode,Type,ConfigBufferState[Numeral[0]]);
  322.  
  323.                 va_end(VarArgs);
  324.  
  325.                 return;
  326.  
  327.             case INFO_UNITTIME:
  328.  
  329.                 SPrintf(&MiniBuffer[1],"%2ld:%02ld",Numeral[0] / 60,Numeral[0] % 60);
  330.  
  331.                 if(Numeral[0] > 0)
  332.                     MiniBuffer[0] = '-';
  333.                 else
  334.                     MiniBuffer[0] = ' ';
  335.  
  336.                 Type = INFO_ONLINETIME;
  337.  
  338.                 break;
  339.  
  340.             case INFO_ONLINECOST:
  341.  
  342.                 memcpy(MiniBuffer,String[0],8);
  343.                 strcat(MiniBuffer,"          ");
  344.  
  345.                 MiniBuffer[8] = 0;
  346.  
  347.                 Type = INFO_ONLINETIME;
  348.  
  349.                 break;
  350.  
  351.             case INFO_CURRENTTIME:
  352.  
  353.                 FormatTime(MiniBuffer,Numeral[0],Numeral[1],Numeral[2]);
  354.                 break;
  355.  
  356.             case INFO_ONLINETIME:
  357.  
  358.                 SPrintf(MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
  359.                 break;
  360.  
  361.             case INFO_BAUDRATE:
  362.  
  363.                 if(LocaleBase)
  364.                     SPrintf(MiniBuffer,"%lD        ",Numeral[0]);
  365.                 else
  366.                     SPrintf(MiniBuffer,"%ld        ",Numeral[0]);
  367.  
  368.                 MiniBuffer[7] = 0;
  369.  
  370.                 break;
  371.  
  372.             case INFO_PROTOCOL:
  373.             case INFO_EMULATION:
  374.  
  375.                 memcpy(MiniBuffer,String[0],12);
  376.                 strcat(MiniBuffer,"           ");
  377.  
  378.                 MiniBuffer[12] = 0;
  379.  
  380.                 break;
  381.  
  382.             case INFO_PARAMETERS:
  383.  
  384.                 if(Mode == MODE_SCREEN_COMPRESSED)
  385.                 {
  386.                     STATIC UBYTE Parities[5] =
  387.                     {
  388.                         'N','E','O','M','S'
  389.                     };
  390.  
  391.                     SPrintf(MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
  392.                 }
  393.                 else
  394.                     SPrintf(MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
  395.  
  396.                 break;
  397.         }
  398.  
  399.         DoInfo(Object,Mode,Type,MiniBuffer);
  400.  
  401.         va_end(VarArgs);
  402.     }
  403. }
  404.  
  405.     /* VisualBeep():
  406.      *
  407.      *    Handle the visual part of the display beep.
  408.      */
  409.  
  410. STATIC BOOL
  411. VisualBeep(ColourTable **OldPtr,ColourTable **NewPtr)
  412. {
  413.     ColourTable *Old,*New;
  414.  
  415.     Old = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
  416.     New = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
  417.  
  418.     if(New && Old)
  419.     {
  420.         ULONG Red,Green,Blue;
  421.         LONG i;
  422.  
  423.         GrabColours(&Window->WScreen->ViewPort,Old);
  424.         CopyColours(Old,New);
  425.  
  426.         for(i = 0 ; i < Old->NumColours ; i++)
  427.         {
  428.             Red        = (Old->Entry[i].Red     >> 24) + 64;
  429.             Green    = (Old->Entry[i].Green     >> 24) + 64;
  430.             Blue    = (Old->Entry[i].Blue     >> 24) + 64;
  431.  
  432.             if(Red > 255)
  433.                 Red = 255;
  434.  
  435.             if(Green > 255)
  436.                 Green = 255;
  437.  
  438.             if(Blue > 255)
  439.                 Blue = 255;
  440.  
  441.             New->Entry[i].Red    = SPREAD(Red);
  442.             New->Entry[i].Green    = SPREAD(Green);
  443.             New->Entry[i].Blue    = SPREAD(Blue);
  444.         }
  445.  
  446.         *OldPtr = Old;
  447.         *NewPtr = New;
  448.  
  449.         return(TRUE);
  450.     }
  451.  
  452.     DeleteColourTable(Old);
  453.     DeleteColourTable(New);
  454.  
  455.     *OldPtr = *NewPtr = NULL;
  456.  
  457.     return(FALSE);
  458. }
  459.  
  460.     /* StatusDisplayServer(VOID):
  461.      *
  462.      *    Yet another asynchronous background task to display
  463.      *    some information.
  464.      */
  465.  
  466. STATIC VOID __saveds
  467. StatusDisplayServer(VOID)
  468. {
  469.         /* Create the interface port. */
  470.  
  471.     if(StatusDisplayPort = CreateMsgPort())
  472.     {
  473.         struct UpdateMessage    *Msg;
  474.         ULONG                     Signals;
  475.  
  476.             /* Ring back... */
  477.  
  478.         Signal(StatusProcess,SIG_HANDSHAKE);
  479.  
  480.             /* Wait for messages or termination signal. */
  481.  
  482.         FOREVER
  483.         {
  484.             Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
  485.  
  486.                 /* Termination? */
  487.  
  488.             if(Signals & SIG_KILL)
  489.                 break;
  490.  
  491.                 /* Message arrival? */
  492.  
  493.             if(Signals & PORTMASK(StatusDisplayPort))
  494.             {
  495.                     /* Process all pending messages. */
  496.  
  497.                 while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  498.                 {
  499.                     DoStatusInfo(Msg->Object,Msg->Mode,Msg->Type,Msg->VanillaMessage.mn_Node.ln_Name);
  500.  
  501.                     FreeVecPooled(Msg);
  502.                 }
  503.             }
  504.         }
  505.  
  506.             /* Remove all pending messages. */
  507.  
  508.         while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  509.             FreeVecPooled(Msg);
  510.  
  511.             /* Remove the msgport. */
  512.  
  513.         DeleteMsgPort(StatusDisplayPort);
  514.     }
  515.  
  516.         /* Lock & quit... */
  517.  
  518.     Forbid();
  519.  
  520.     Signal(StatusProcess,SIG_HANDSHAKE);
  521.  
  522.     RemTask(StatusDisplayTask = NULL);
  523. }
  524.  
  525.     /* StatusServer():
  526.      *
  527.      *    Asynchronous process to continuosly display the current
  528.      *    terminal settings.
  529.      */
  530.  
  531. VOID __saveds
  532. StatusServer()
  533. {
  534.     STATIC struct timeval     OnlineTime,
  535.                              LastTime,
  536.                              TempTime;
  537.     STATIC LONG                 SecCount,
  538.                              MinCount,
  539.                              BeepCount;
  540.  
  541.     STATIC BOOL                 LocalWasOnline;
  542.     BOOL                     LocalIsOnline;
  543.  
  544.     struct TextBox            *BoxArray[4],
  545.                             *BoxList = NULL,
  546.                             *Box;
  547.  
  548.     struct RastPort            *RPort;
  549.  
  550.     APTR                     SomeObject;
  551.     struct ObjectCarrier     Carrier;
  552.  
  553.     struct timerequest        *StatusTimeRequest;
  554.     struct MsgPort            *StatusTimePort;
  555.     struct timeval             Now;
  556.  
  557.     BOOL                     Background            = FALSE,
  558.                              FlashIt            = FALSE,
  559.                              SetColours            = FALSE,
  560.                              StandardColours    = TRUE,
  561.                              KeepGoing            = TRUE,
  562.                              Beeping            = FALSE;
  563.  
  564.     WORD                     StatusMode            = Config->ScreenConfig->StatusLine;
  565.     WORD                     ShowCounter        = 0;
  566.  
  567.     UBYTE                     LastProtocol[40],
  568.                              LastEmulationName[40];
  569.  
  570.     LONG                     LastFrozen            = -1,
  571.                              LastEmulation        = -1,
  572.                              LastBitsPerChar    = -1,
  573.                              LastParity            = -1,
  574.                              LastStopBits        = -1,
  575.                              LastStatus            = -1;
  576.  
  577.     LONG                     LastBaud            = -1;
  578.  
  579.     LONG                     i,
  580.                              ThisHour,
  581.                              ThisMinute,
  582.                              BoxCounter = 0,
  583.                              FullWidth;
  584.     LONG                     ColumnLeft[4],
  585.                              ColumnWidth[4],
  586.                              Max,
  587.                              Len;
  588.  
  589.     ColourTable                *Old = NULL,*New = NULL;
  590.  
  591.     BOOL                     AllFine = TRUE;
  592.     LONG                     Mode;
  593.  
  594.     StatusLineWidth = 0;
  595.  
  596.     LastProtocol[0] = 0;
  597.  
  598.     LastEmulationName[0] = 0;
  599.  
  600.     LocalizeString(ConfigBufferState,MSG_TERMSTATUSDISPLAY_FROZEN_TXT,MSG_TERMSTATUSDISPLAY_RECORDING_TXT);
  601.     LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
  602.     LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
  603.     LocalizeString(ConfigStatus,MSG_TERMAUX_READY_TXT,MSG_TERMAUX_RECORD_LINE_TXT);
  604.  
  605.     if(StatusWindow)
  606.         RPort = StatusWindow->RPort;
  607.     else
  608.         RPort = StatusRPort;
  609.  
  610.     if(RPort)
  611.     {
  612.         SetAPen(RPort,Pens[BACKGROUNDPEN]);
  613.         FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  614.  
  615.             /* Render the information. */
  616.  
  617.         if(StatusWindow)
  618.             SZ_SizeSetup(StatusWindow->WScreen,&UserFont);
  619.         else
  620.             SZ_SizeSetup(Window->WScreen,&UserFont);
  621.  
  622.         if(StatusMode == STATUSLINE_COMPRESSED)
  623.         {
  624.             StatusOffset = (StatusDisplayWidth - 80 * UserFontWidth) / 2;
  625.  
  626.             SetAPen(RPort,Pens[TEXTPEN]);
  627.             FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  628.  
  629.             SetPens(RPort,Pens[BACKGROUNDPEN],Pens[TEXTPEN],JAM2);
  630.  
  631.             SetFont(RPort,UserTextFont);
  632.         }
  633.         else
  634.         {
  635.             SetBPen(RPort,Pens[BACKGROUNDPEN]);
  636.  
  637.                 /* Draw a separating line. */
  638.  
  639.             if(!Config->ScreenConfig->SplitStatus)
  640.                 DrawSeparator(RPort);
  641.  
  642.             SetAPen(RPort,Pens[TEXTPEN]);
  643.  
  644.             ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
  645.             ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
  646.             ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
  647.             ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
  648.  
  649.             Max = 0;
  650.  
  651.             for(i = 0 ; ConfigStatus[i] ; i++)
  652.             {
  653.                 if((Len = SZ_BoxWidth(strlen(ConfigStatus[i]))) > Max)
  654.                     Max = Len;
  655.             }
  656.  
  657.             for(i = 0 ; ConfigBufferState[i] ; i++)
  658.             {
  659.                 if((Len = SZ_BoxWidth(strlen(ConfigBufferState[i]))) > Max)
  660.                     Max = Len;
  661.             }
  662.  
  663.             ColumnWidth[0] = Max;
  664.  
  665.             Max = SZ_BoxWidth(12);
  666.  
  667.             for(i = 0 ; ConfigEmulation[i] ; i++)
  668.             {
  669.                 if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
  670.                     Max = Len;
  671.             }
  672.  
  673.             ColumnWidth[1] = Max;
  674.  
  675.             Max = SZ_BoxWidth(10);
  676.  
  677.             for(i = 0 ; ConfigParity[i] ; i++)
  678.             {
  679.                 if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
  680.                     Max = Len;
  681.             }
  682.  
  683.             ColumnWidth[2] = Max;
  684.  
  685.             ColumnWidth[3] = SZ_BoxWidth(8);
  686.  
  687.             FullWidth = 0;
  688.  
  689.             for(i = 0 ; i < 4 ; i++)
  690.                 FullWidth += ColumnWidth[i] + ColumnLeft[i];
  691.  
  692.             FullWidth += 4 + 3 * InterWidth;
  693.  
  694.             Carrier.FullWidth    = FullWidth;
  695.             Carrier.FirstColumn    = ColumnLeft[0] + 2;
  696.  
  697.             if(!Config->ScreenConfig->SplitStatus)
  698.             {
  699.                 if(FullWidth > StatusDisplayWidth)
  700.                     SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
  701.                 else
  702.                     SZ_SetLeftEdge(StatusDisplayLeft + (StatusDisplayWidth - FullWidth) / 2 + ColumnLeft[0] + 2);
  703.  
  704.                 SZ_SetAbsoluteTop(StatusDisplayTop + 3);
  705.                 SZ_SetTopEdge(StatusDisplayTop + 3);
  706.             }
  707.             else
  708.             {
  709.                 SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
  710.  
  711.                 SZ_SetAbsoluteTop(StatusDisplayTop + 1);
  712.                 SZ_SetTopEdge(StatusDisplayTop + 1);
  713.             }
  714.  
  715.             SZ_SetWidth(ColumnWidth[0]);
  716.  
  717.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  718.                 SZ_Lines,        2,
  719.                 SZ_AutoWidth,    TRUE,
  720.             TAG_DONE);
  721.  
  722.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
  723.  
  724.             SZ_SetWidth(ColumnWidth[1]);
  725.             SZ_AddLeftOffset(ColumnLeft[1]);
  726.  
  727.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  728.                 SZ_Lines,        2,
  729.                 SZ_AutoWidth,    TRUE,
  730.                 SZ_NewColumn,    TRUE,
  731.             TAG_DONE);
  732.  
  733.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
  734.  
  735.             SZ_SetWidth(ColumnWidth[2]);
  736.             SZ_AddLeftOffset(ColumnLeft[2]);
  737.  
  738.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  739.                 SZ_Lines,        2,
  740.                 SZ_AutoWidth,    TRUE,
  741.                 SZ_NewColumn,    TRUE,
  742.             TAG_DONE);
  743.  
  744.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
  745.  
  746.             SZ_SetWidth(ColumnWidth[3]);
  747.             SZ_AddLeftOffset(ColumnLeft[3]);
  748.  
  749.             BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
  750.                 SZ_Lines,        2,
  751.                 SZ_AutoWidth,    TRUE,
  752.                 SZ_NewColumn,    TRUE,
  753.             TAG_DONE);
  754.  
  755.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
  756.  
  757.             if(!Box)
  758.                 AllFine = FALSE;
  759.             else
  760.                 SZ_DrawBoxes(RPort,BoxList);
  761.         }
  762.     }
  763.     else
  764.         AllFine = TRUE;
  765.  
  766.     if((UpdateSig = AllocSignal(-1)) == -1)
  767.         AllFine = FALSE;
  768.     else
  769.         UpdateMask = 1L << UpdateSig;
  770.  
  771.         /* Everything fine so far? */
  772.  
  773.     if(AllFine)
  774.     {
  775.         Forbid();
  776.  
  777.             /* Create the display server task. */
  778.  
  779.         if(StatusDisplayTask = CreateTask("term Status Display Task",5,StatusDisplayServer,4000))
  780.         {
  781.             ClrSignal(SIG_HANDSHAKE);
  782.  
  783.             Wait(SIG_HANDSHAKE);
  784.         }
  785.  
  786.         Permit();
  787.     }
  788.  
  789.         /* Is the display server task up and running? */
  790.  
  791.     if(StatusDisplayTask)
  792.     {
  793.             /* Create a timer device request. */
  794.  
  795.         if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
  796.         {
  797.             if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
  798.             {
  799.                 if(!OpenDevice(TIMERNAME,UNIT_VBLANK,StatusTimeRequest,0))
  800.                 {
  801.                         /* Signal our father process
  802.                          * that we're running.
  803.                          */
  804.  
  805.                     Signal(ThisProcess,SIG_HANDSHAKE);
  806.  
  807.                     if(RPort)
  808.                     {
  809.                         if(StatusMode == STATUSLINE_COMPRESSED)
  810.                         {
  811.                             Mode = MODE_SCREEN_COMPRESSED;
  812.  
  813.                             SomeObject = RPort;
  814.                         }
  815.                         else
  816.                         {
  817.                             Mode = MODE_SCREEN_NORMAL;
  818.  
  819.                             Carrier.RPort        = RPort;
  820.                             Carrier.BoxArray    = BoxArray;
  821.                             Carrier.BoxList        = BoxList;
  822.  
  823.                             SomeObject = &Carrier;
  824.                         }
  825.  
  826.                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
  827.                     }
  828.  
  829.                         /* Keep on displaying. */
  830.  
  831.                     while(KeepGoing)
  832.                     {
  833.                             /* Are we to quit? */
  834.  
  835.                         if(CheckSignal(SIG_KILL))
  836.                             KeepGoing = FALSE;
  837.  
  838.                             /* Get the current time. */
  839.  
  840.                         GetSysTime(&Now);
  841.  
  842.                         ObtainSemaphoreShared(&OnlineSemaphore);
  843.  
  844.                             /* A connection has just
  845.                              * been established.
  846.                              */
  847.  
  848.                         if(Online && !LocalWasOnline)
  849.                         {
  850.                             OnlineTime        = Now;
  851.                             LocalWasOnline    = TRUE;
  852.                         }
  853.  
  854.                         ReleaseSemaphore(&OnlineSemaphore);
  855.  
  856.                             /* Print the current time. */
  857.  
  858.                         ThisHour    = (Now.tv_secs % (24 * 60 * 60)) / (60 * 60);
  859.                         ThisMinute    = (Now.tv_secs % (60 * 60)) / 60;
  860.  
  861.                         UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,Now.tv_secs % 60);
  862.  
  863.                             /* Handle routine checkup actions. */
  864.  
  865.                         if(SecCount++ >= 4)
  866.                         {
  867.                             Signal(ThisProcess,SIG_CHECK);
  868.                             SecCount = 0;
  869.                         }
  870.  
  871.                         ObtainSemaphoreShared(&OnlineSemaphore);
  872.                         LocalIsOnline = Online;
  873.                         ReleaseSemaphore(&OnlineSemaphore);
  874.  
  875.                         if(LocalIsOnline)
  876.                         {
  877.                                 /* Show the time
  878.                                  * we have been online
  879.                                  * yet.
  880.                                  */
  881.  
  882.                             TempTime = Now;
  883.  
  884.                             SubTime(&TempTime,&OnlineTime);
  885.  
  886.                             if(Now.tv_secs != LastTime.tv_secs)
  887.                             {
  888.                                 WORD What;
  889.  
  890.                                 LastTime = Now;
  891.  
  892.                                 switch(Config->ScreenConfig->TimeMode)
  893.                                 {
  894.                                     case ONLINETIME_TIME:
  895.  
  896.                                         What = SHOW_OnlineTime;
  897.                                         break;
  898.  
  899.                                     case ONLINETIME_COST:
  900.  
  901.                                         What = SHOW_Cost;
  902.                                         break;
  903.  
  904.                                     case ONLINETIME_BOTH:
  905.  
  906.                                         if(TempTime.tv_secs)
  907.                                         {
  908.                                             if(!(TempTime.tv_secs % 5))
  909.                                                 ShowCounter = (ShowCounter + 1) % 3;
  910.                                         }
  911.  
  912.                                         switch(ShowCounter)
  913.                                         {
  914.                                             case 0:
  915.  
  916.                                                 What = SHOW_OnlineTime;
  917.                                                 break;
  918.  
  919.                                             case 1:
  920.  
  921.                                                 What = SHOW_Cost;
  922.                                                 break;
  923.  
  924.                                             case 2:
  925.  
  926.                                                 What = SHOW_UnitTime;
  927.                                                 break;
  928.                                         }
  929.  
  930.                                         break;
  931.                                 }
  932.  
  933.                                 OnlineMinutes = TempTime.tv_secs / 60;
  934.  
  935.                                 switch(What)
  936.                                 {
  937.                                     case SHOW_OnlineTime:
  938.  
  939.                                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime.tv_secs % 86400) / 3600,(TempTime.tv_secs % 3600) / 60,TempTime.tv_secs % 60);
  940.                                         break;
  941.  
  942.                                     case SHOW_Cost:
  943.  
  944.                                         UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,CreateSum((QueryAccountantCost() + 5000) / 10000,TRUE));
  945.                                         break;
  946.  
  947.                                     case SHOW_UnitTime:
  948.  
  949.                                         UpdateInfo(SomeObject,Mode,INFO_UNITTIME,QueryAccountantTime(NULL));
  950.                                         break;
  951.                                 }
  952.                             }
  953.                         }
  954.                         else
  955.                         {
  956.                             if(LocalWasOnline)
  957.                             {
  958.                                 LocalWasOnline = FALSE;
  959.                                 UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime.tv_secs % 86400) / 3600,(TempTime.tv_secs % 3600) / 60,TempTime.tv_secs % 60);
  960.                             }
  961.                         }
  962.  
  963.                             /* Take care of the visual beep
  964.                              * if enabled.
  965.                              */
  966.  
  967.                         if(Beeping)
  968.                         {
  969.                             if(!(BeepCount--))
  970.                             {
  971.                                 Beeping = FALSE;
  972.  
  973.                                 LoadColourTable(VPort,Old,NULL,0);
  974.  
  975.                                 DeleteColourTable(Old);
  976.                                 DeleteColourTable(New);
  977.  
  978.                                 Old = New = NULL;
  979.  
  980.                                     /* Clear the signal bit. */
  981.  
  982.                                 ClrSignal(SIG_BELL);
  983.                             }
  984.                         }
  985.  
  986.                             /* Are we to show a visual beep? */
  987.  
  988.                         if(CheckSignal(SIG_BELL))
  989.                         {
  990.                             if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
  991.                                 DisplayBeep(Window->WScreen);
  992.                             else
  993.                             {
  994.                                 if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
  995.                                 {
  996.                                     if(VisualBeep(&Old,&New))
  997.                                     {
  998.                                         LoadColourTable(VPort,New,NULL,0);
  999.  
  1000.                                         Beeping = TRUE;
  1001.  
  1002.                                         BeepCount = 1;
  1003.                                     }
  1004.                                 }
  1005.                             }
  1006.                         }
  1007.  
  1008.                             /* Display the current terminal
  1009.                              * status.
  1010.                              */
  1011.  
  1012.                         if(LastStatus != Status)
  1013.                             UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = Status);
  1014.  
  1015.                             /* Show the current transfer
  1016.                              * protocol.
  1017.                              */
  1018.  
  1019.                         if(strcmp(LastProtocol,TransferProtocolName))
  1020.                         {
  1021.                             strcpy(LastProtocol,TransferProtocolName);
  1022.  
  1023.                             if(LastProtocol[0])
  1024.                                 UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,LastProtocol);
  1025.                             else
  1026.                                 UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,"-");
  1027.                         }
  1028.  
  1029.                             /* Show the current baud
  1030.                              * rate.
  1031.                              */
  1032.  
  1033.                         if(LastBaud != Config->SerialConfig->BaudRate)
  1034.                             UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config->SerialConfig->BaudRate);
  1035.  
  1036.                             /* Show the current
  1037.                              * terminal font.
  1038.                              */
  1039.  
  1040.                         if(LastFrozen != BufferFrozen)
  1041.                         {
  1042.                             LastFrozen = BufferFrozen;
  1043.  
  1044.                             UpdateInfo(SomeObject,Mode,INFO_BUFFER,LastFrozen != TRUE);
  1045.                         }
  1046.  
  1047.                             /* Show the current terminal
  1048.                              * emulation.
  1049.                              */
  1050.  
  1051.                         if(LastEmulation != Config->TerminalConfig->EmulationMode || (Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
  1052.                         {
  1053.                             LastEmulation = Config->TerminalConfig->EmulationMode;
  1054.  
  1055.                             if(Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1056.                             {
  1057.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
  1058.  
  1059.                                 strcpy(LastEmulationName,EmulationName);
  1060.                             }
  1061.                             else
  1062.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
  1063.                         }
  1064.  
  1065.                             /* Show the current serial
  1066.                              * parameters (parity, etc).
  1067.                              */
  1068.  
  1069.                         if(LastBitsPerChar != Config->SerialConfig->BitsPerChar || LastParity != Config->SerialConfig->Parity || LastStopBits != Config->SerialConfig->StopBits)
  1070.                         {
  1071.                             LastBitsPerChar    = Config->SerialConfig->BitsPerChar;
  1072.                             LastParity        = Config->SerialConfig->Parity;
  1073.                             LastStopBits    = Config->SerialConfig->StopBits;
  1074.  
  1075.                             UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
  1076.                         }
  1077.  
  1078.                             /* Wait another half a second. */
  1079.  
  1080.                         if(KeepGoing)
  1081.                         {
  1082.                             ULONG    Mask;
  1083.                             BOOL    ResetTime = FALSE;
  1084.  
  1085.                             StatusTimeRequest->tr_node.io_Command    = TR_ADDREQUEST;
  1086.                             StatusTimeRequest->tr_time.tv_secs        = 0;
  1087.                             StatusTimeRequest->tr_time.tv_micro        = MILLION / 2;
  1088.  
  1089.                             SendIO(StatusTimeRequest);
  1090.  
  1091.                             FOREVER
  1092.                             {
  1093.                                 Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort) | SIG_CLOSEWINDOW | SIG_RESETTIME | UpdateMask);
  1094.  
  1095.                                 if(Mask & UpdateMask)
  1096.                                 {
  1097.                                     Signal(ThisProcess,SIG_HANDSHAKE);
  1098.  
  1099.                                     Wait(UpdateMask);
  1100.  
  1101.                                     NeedFullRefresh = TRUE;
  1102.  
  1103.                                     UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = Status);
  1104.                                 }
  1105.  
  1106.                                     /* Close the window and keep quiet? */
  1107.  
  1108.                                 if(Mask & SIG_CLOSEWINDOW)
  1109.                                 {
  1110.                                     Forbid();
  1111.  
  1112.                                     if(StatusDisplayTask)
  1113.                                     {
  1114.                                         Signal(StatusDisplayTask,SIG_KILL);
  1115.  
  1116.                                         ClrSignal(SIG_HANDSHAKE);
  1117.  
  1118.                                         Wait(SIG_HANDSHAKE);
  1119.                                     }
  1120.  
  1121.                                     if(BoxList)
  1122.                                     {
  1123.                                         SZ_FreeBoxes(BoxList);
  1124.  
  1125.                                         BoxList = NULL;
  1126.                                     }
  1127.  
  1128.                                     SomeObject = NULL;
  1129.  
  1130.                                     Signal(ThisProcess,SIG_HANDSHAKE);
  1131.  
  1132.                                     Config->ScreenConfig->StatusLine = STATUSLINE_DISABLED;
  1133.  
  1134.                                     Permit();
  1135.                                 }
  1136.  
  1137.                                 if(Mask & SIG_BELL)
  1138.                                 {
  1139.                                     if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
  1140.                                         DisplayBeep(Window->WScreen);
  1141.                                     else
  1142.                                     {
  1143.                                         if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
  1144.                                         {
  1145.                                             if(VisualBeep(&Old,&New))
  1146.                                             {
  1147.                                                 LoadColourTable(VPort,New,NULL,0);
  1148.  
  1149.                                                 Beeping = TRUE;
  1150.  
  1151.                                                 BeepCount = 1;
  1152.                                             }
  1153.                                         }
  1154.                                     }
  1155.                                 }
  1156.  
  1157.                                     /* Reset the online time counter. */
  1158.  
  1159.                                 if(Mask & SIG_RESETTIME)
  1160.                                     ResetTime = TRUE;
  1161.  
  1162.                                 if(Mask & PORTMASK(StatusTimePort))
  1163.                                 {
  1164.                                     WaitIO(StatusTimeRequest);
  1165.  
  1166.                                     break;
  1167.                                 }
  1168.                             }
  1169.  
  1170.                                 /* Reset the online time. */
  1171.  
  1172.                             if(ResetTime)
  1173.                                 GetSysTime(&OnlineTime);
  1174.  
  1175.                                 /* Count up to a minute. */
  1176.  
  1177.                             if(MinCount++ == 120)
  1178.                             {
  1179.                                 MinCount = 0;
  1180.  
  1181.                                     /* Time limit present? */
  1182.  
  1183.                                 if(LimitCount > 0)
  1184.                                     LimitCount--;
  1185.  
  1186.                                     /* Limit reached? */
  1187.  
  1188.                                 if(!LimitCount)
  1189.                                     Signal(ThisProcess,SIG_CHECK);
  1190.                             }
  1191.                         }
  1192.  
  1193.                             /* Make the colours blink. */
  1194.  
  1195.                         if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping)
  1196.                         {
  1197.                             if(Screen == IntuitionBase->FirstScreen)
  1198.                             {
  1199.                                     /* No main screen window active? */
  1200.  
  1201.                                 if(StatusWindow)
  1202.                                 {
  1203.                                     if(!(Window->Flags & WFLG_WINDOWACTIVE) && !(StatusWindow->Flags & WFLG_WINDOWACTIVE))
  1204.                                         StandardColours = TRUE;
  1205.                                 }
  1206.                                 else
  1207.                                 {
  1208.                                     if(!(Window->Flags & WFLG_WINDOWACTIVE))
  1209.                                         StandardColours = TRUE;
  1210.                                 }
  1211.  
  1212.                                     /* Menu button pressed or window disabled? */
  1213.  
  1214.                                 if(Window->Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
  1215.                                     StandardColours = TRUE;
  1216.  
  1217.                                     /* User is currently dragging the
  1218.                                      * mouse in order to mark something
  1219.                                      * on the screen?
  1220.                                      */
  1221.  
  1222.                                 if(Marking)
  1223.                                     StandardColours = TRUE;
  1224.  
  1225.                                 Background = FALSE;
  1226.                             }
  1227.                             else
  1228.                             {
  1229.                                 if(!Background)
  1230.                                     StandardColours = TRUE;
  1231.  
  1232.                                 Background = TRUE;
  1233.                             }
  1234.  
  1235.                             if(StandardColours)
  1236.                             {
  1237.                                 if(!SetColours)
  1238.                                 {
  1239.                                     LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1240.  
  1241.                                     SetColours = TRUE;
  1242.                                 }
  1243.  
  1244.                                 StandardColours = FlashIt = FALSE;
  1245.                             }
  1246.                             else
  1247.                             {
  1248.                                     /* Are we to flash the display? */
  1249.  
  1250.                                 if(Config->ScreenConfig->Blinking)
  1251.                                 {
  1252.                                     if(Screen == IntuitionBase->FirstScreen)
  1253.                                     {
  1254.                                         if(FlashIt)
  1255.                                         {
  1256.                                             LoadColourTable(VPort,BlinkColourTable,BlinkColours,PaletteSize);
  1257.  
  1258.                                             SetColours = FALSE;
  1259.                                         }
  1260.                                         else
  1261.                                         {
  1262.                                             LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1263.  
  1264.                                             SetColours = TRUE;
  1265.                                         }
  1266.                                     }
  1267.  
  1268.                                     FlashIt ^= TRUE;
  1269.                                 }
  1270.                             }
  1271.                         }
  1272.                     }
  1273.  
  1274.                     CloseDevice(StatusTimeRequest);
  1275.                 }
  1276.  
  1277.                 DeleteIORequest(StatusTimeRequest);
  1278.             }
  1279.  
  1280.             DeleteMsgPort(StatusTimePort);
  1281.         }
  1282.  
  1283.         if(Old)
  1284.             LoadColourTable(VPort,Old,NULL,0);
  1285.  
  1286.         DeleteColourTable(Old);
  1287.         DeleteColourTable(New);
  1288.  
  1289.         if(StatusDisplayTask)
  1290.         {
  1291.             Forbid();
  1292.  
  1293.             Signal(StatusDisplayTask,SIG_KILL);
  1294.  
  1295.             ClrSignal(SIG_HANDSHAKE);
  1296.  
  1297.             Wait(SIG_HANDSHAKE);
  1298.  
  1299.             Permit();
  1300.         }
  1301.  
  1302.         if(BoxList)
  1303.             SZ_FreeBoxes(BoxList);
  1304.     }
  1305.  
  1306.     if(UpdateSig != -1)
  1307.         FreeSignal(UpdateSig);
  1308.  
  1309.         /* Signal the father process that we're done
  1310.          * and quietly remove ourselves.
  1311.          */
  1312.  
  1313.     Forbid();
  1314.  
  1315.     Signal(ThisProcess,SIG_HANDSHAKE);
  1316.  
  1317.     StatusProcess = NULL;
  1318. }
  1319.  
  1320.     /* ForceStatusUpdate():
  1321.      *
  1322.      *    Make sure that the status display gets updated
  1323.      *    as soon as possible.
  1324.      */
  1325.  
  1326. VOID
  1327. ForceStatusUpdate()
  1328. {
  1329.     if(StatusProcess && Window)
  1330.     {
  1331.             // Stop the execution
  1332.  
  1333.         Forbid();
  1334.  
  1335.         Signal(StatusProcess,UpdateMask);
  1336.  
  1337.         ClrSignal(SIG_HANDSHAKE);
  1338.  
  1339.         Wait(SIG_HANDSHAKE);
  1340.  
  1341.         Permit();
  1342.  
  1343.             // Ok, the status process is waiting, now update the data
  1344.  
  1345.         DropMarker();
  1346.  
  1347.         UpdateTerminalLimits();
  1348.  
  1349.             // Clear the window
  1350.  
  1351.         SetAPen(Window->RPort,Pens[BACKGROUNDPEN]);
  1352.         FillBox(Window->RPort,Window->BorderLeft,Window->BorderTop,Window->Width - (Window->BorderLeft + Window->BorderRight),Window->Height - (Window->BorderTop + Window->BorderBottom));
  1353.  
  1354.             // Restart the status process
  1355.  
  1356.         Signal(StatusProcess,UpdateMask);
  1357.  
  1358.             // Repaint the window border, in case it got trashed
  1359.  
  1360.         RefreshWindowFrame(Window);
  1361.     }
  1362. }
  1363.